/*
 * Copyright (c) 2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @file queue.h
 *
 * @brief 声明串行队列提供的C++接口.
 *
 * @since 10
 * @version 1.0
 */
#ifndef FFRT_API_CPP_QUEUE_H
#define FFRT_API_CPP_QUEUE_H

#include "c/queue.h"
#include "cpp/task.h"

namespace ffrt {
class queue_attr : public ffrt_queue_attr_t {
public:
    queue_attr()
    {
        ffrt_queue_attr_init(this);
    }

    ~queue_attr()
    {
        ffrt_queue_attr_destroy(this);
    }

    queue_attr(const queue_attr&) = delete;
    queue_attr& operator=(const queue_attr&) = delete;

    /**
     * @brief 设置串行队列qos属性.
     *
     * @param attr qos属性值.
     * @since 10
     * @version 1.0
     */
    inline queue_attr& qos(enum qos qos)
    {
        ffrt_queue_attr_set_qos(this, static_cast<ffrt_qos_t>(qos));
        return *this;
    }

    /**
     * @brief 获取串行队列qos属性.
     *
     * @return 返回串行队列的qos属性
     * @since 10
     * @version 1.0
     */
    inline enum qos qos() const
    {
        return static_cast<enum qos>(ffrt_queue_attr_get_qos(this));
    }
};

class queue {
public:
    queue(const char* name, const queue_attr& attr = {})
    {
        queue_handle = ffrt_queue_create(ffrt_queue_serial, name, &attr);
    }

    ~queue()
    {
        ffrt_queue_destroy(queue_handle);
    }

    queue(queue const&) = delete;
    void operator=(queue const&) = delete;

    /**
     * @brief 提交一个任务到队列中调度执行.
     *
     * @param func 任务执行体函数闭包.
     * @since 10
     * @version 1.0
     */
    inline void submit(std::function<void()>& func)
    {
        ffrt_queue_submit(queue_handle, create_function_wrapper(func, ffrt_function_kind_queue), nullptr);
    }

    /**
     * @brief 提交一个特定属性的任务到队列中调度执行.
     *
     * @param func 任务执行体函数闭包.
     * @param attr 任务属性.
     * @since 10
     * @version 1.0
     */
    inline void submit(std::function<void()>& func, const task_attr& attr)
    {
        ffrt_queue_submit(queue_handle, create_function_wrapper(func, ffrt_function_kind_queue), &attr);
    }

    /**
     * @brief 提交一个任务到队列中调度执行.
     *
     * @param func 任务执行体函数闭包.
     * @since 10
     * @version 1.0
     */
    inline void submit(std::function<void()>&& func)
    {
        ffrt_queue_submit(queue_handle, create_function_wrapper(std::move(func), ffrt_function_kind_queue), nullptr);
    }

    /**
     * @brief 提交一个特定属性的任务到队列中调度执行.
     *
     * @param func 任务执行体函数闭包.
     * @param attr 任务属性.
     * @since 10
     * @version 1.0
     */
    inline void submit(std::function<void()>&& func, const task_attr& attr)
    {
        ffrt_queue_submit(queue_handle, create_function_wrapper(std::move(func), ffrt_function_kind_queue), &attr);
    }

    /**
     * @brief 提交一个任务到队列中调度执行并返回任务句柄.
     *
     * @param func 任务执行体函数闭包.
     * @return 提交成功返回非空任务句柄
               提交失败返回空指针
     * @since 10
     * @version 1.0
     */
    inline task_handle submit_h(std::function<void()>& func)
    {
        return ffrt_queue_submit_h(queue_handle, create_function_wrapper(func, ffrt_function_kind_queue), nullptr);
    }

    /**
     * @brief 提交一个特定属性的任务到队列中调度执行并返回任务句柄.
     *
     * @param func 任务执行体函数闭包.
     * @param attr 任务属性.
     * @return 提交成功返回非空任务句柄
               提交失败返回空指针
     * @since 10
     * @version 1.0
     */
    inline task_handle submit_h(std::function<void()>& func, const task_attr& attr)
    {
        return ffrt_queue_submit_h(queue_handle, create_function_wrapper(func, ffrt_function_kind_queue), &attr);
    }

    /**
     * @brief 提交一个任务到队列中调度执行并返回任务句柄.
     *
     * @param func 任务执行体函数闭包.
     * @return 提交成功返回非空任务句柄
               提交失败返回空指针
     * @since 10
     * @version 1.0
     */
    inline task_handle submit_h(std::function<void()>&& func)
    {
        return ffrt_queue_submit_h(
            queue_handle, create_function_wrapper(std::move(func), ffrt_function_kind_queue), nullptr);
    }

    /**
     * @brief 提交一个特定属性的任务到队列中调度执行并返回任务句柄.
     *
     * @param func 任务执行体函数闭包.
     * @param attr 任务属性.
     * @return 提交成功返回非空任务句柄
               提交失败返回空指针
     * @since 10
     * @version 1.0
     */
    inline task_handle submit_h(std::function<void()>&& func, const task_attr& attr)
    {
        return ffrt_queue_submit_h(
            queue_handle, create_function_wrapper(std::move(func), ffrt_function_kind_queue), &attr);
    }

    /**
     * @brief 取消任务.
     *
     * @param handle 任务句柄.
     * @return 取消任务成功返回0
               取消任务成功返回-1
     * @since 10
     * @version 1.0
     */
    inline int cancel(task_handle& handle)
    {
        return ffrt_queue_cancel(handle);
    }

    /**
     * @brief 等待任务执行完成.
     *
     * @param handle 任务句柄.
     * @since 10
     * @version 1.0
     */
    inline void wait(task_handle& handle)
    {
        return ffrt_queue_wait(handle);
    }

private:
    ffrt_queue_t queue_handle = nullptr;
};
} // namespace ffrt

#endif // FFRT_API_CPP_QUEUE_H